package com.chengzhi.structure;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description:
 * @author: ruanchengzhi
 * @create: 2020-04-22 14:43
 **/
public class MyQueue<E> {

    private final List<E> list;
    private final int limit;
    private final Lock lock = new ReentrantLock();
    private final Condition notEmpty = lock.newCondition();//非空
    private final Condition notFull = lock.newCondition();//没满

    public MyQueue(int limit) {
        this.limit = limit;
        this.list = new ArrayList<E>();
    }

    public void put(E e) {
        lock.lock();
        try {
            while (list.size() >= limit) {
                notFull.await();
            }
            list.add(e);
            System.out.println("add ------ " + e);
            notEmpty.notifyAll();
        } catch (Exception e2) {
            // TODO: handle exception
        } finally {
            lock.unlock();
        }
    }

    public E take() {
        lock.lock();
        try {
            while (list.size() == 0) {
                notEmpty.await();
            }
            E e = list.remove(0);
            System.out.println("take ---- " + e);
            notFull.notifyAll();
            return e;
        } catch (Exception e2) {
            return null;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        MyQueue<Integer> queue = new MyQueue<>(4);
        new Thread(() -> {
            queue.put(1);
            queue.put(2);
            queue.put(3);
            queue.put(4);
            queue.put(5);
        }).start();
        new Thread(() -> {
            queue.take();
        }).start();
    }
}
